#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "words.h"
#include "shellsort.h"
#include "dict_idx.h"
#include "dict_info.h"

//char  retstr[39429];
int w_arr_len=0;
int arrindex(char *word,WORD_IDX *word_idx, DICT_INFO *dict_info);//find the word 'wordx' in the idx arr;
//char *readf(const char * filename)
int readf(const char * filename,char * retstr,int * slen)
{
	/**
	 *open the file
	 */
	FILE* stream=fopen(filename,"rb");
	int bool= fseek(stream,0,SEEK_END);
	int fsize;
	if(bool==0){
		fsize=ftell(stream);
		//printf("open success!\n");
	}else{
		perror("open file failed");
		return (1);
	}
	printf("fsize:%ld\n",ftell(stream));
	rewind(stream);
	printf("rewind pos:%ld\n",ftell(stream));
	

	/**
	 *find all words
	 */
	char *ch;
	ch=(char*)malloc(fsize);
	memset(ch,0,fsize);

	int pos=0;
	static char *warr[100*1024*1024];
	int len=0;//all english str length;
	int c;
	memset(warr,0,fsize);
	while(!(feof(stream)))
	{//copy all the english words
		c=fgetc(stream);
		if(isalpha(c)){
			ch[pos++]=c;
			//printf("%d ",pos);
			warr[len++]=(char*)&(ch[pos-1]);
			while(!(feof(stream)))
			{
				c=fgetc(stream);
				if(isalpha(c)){
					ch[pos++]=c;
				}else{
					ch[pos++]='\0';
					break;
				}
			}
		}
		if(pos>=fsize||pos>1024*256)break;
	}
	ch[pos]='\0';
	fclose(stream);
	printf("-----close file---");
	/**
	 *counter the words 
	 */
	if(len<=0)return 2;
	printf("\n*all words num:%d*",len);
	static struct wordnode counter_arr[1024*1024];
	int all_words_len=1;
	int i=1;
	sprintf(counter_arr[0].word,"%s",warr[0]);
	counter_arr[0].counter=1;
	for(;i<len;++i){
		if(strlen(warr[i])<2)continue;
		int isnew=1;
		int j=0;
		while(j<all_words_len)
		{
			if(strcasecmp(warr[i],counter_arr[j].word)==0){
				isnew=0;
				counter_arr[j].counter++;
				break;
			}
			++j;
		}
		if(isnew){
			sprintf(counter_arr[all_words_len].word,"%s",warr[i]);
			counter_arr[all_words_len++].counter=1;
			//printf("%s,is new\n",warr[i]);

		}else{
			//printf("%s,is old\n",warr[i]);
		}
		//printf("%d:%s ",i,warr[i]);
	}
	shell_sort(counter_arr,all_words_len);
	//find word in dict file
	char * idxname="oxford-gb.idx";
	DICT_INFO dict_info;
	dict_info.wordcount=39429;
	dict_info.idxfilesize=721264;

	WORD_IDX *idx=(WORD_IDX*)malloc(sizeof(WORD_IDX)*dict_info.wordcount);//allocate the mem for the index file; 
	printf("%d\n",
			(int)get_words(
				idxname,
				&dict_info,
				idx)
			);//read the index file,save to idx;
	//return (1);
	int w_arr_len=0;
	static char *w_arr[1024*1024];
	i=0;
	while(i<all_words_len){
		char *wordx=counter_arr[i].word;
		int pp=arrindex(wordx,idx,&dict_info);//find the word 'wordx' in the idx arr;
		counter_arr[i].counter=pp;
		if(pp>0){
			w_arr[w_arr_len++]=wordx;
			//if(pp%1==0)printf("%s,%d.",wordx,pp);
		}
		++i;
	}
	i=0;
	//int slen=0;
	*slen=0;
	//strlen+=sprintf(retstr+slen,"[");
	while(i<w_arr_len-1){
		printf("%s,",w_arr[i]);
		*slen+=sprintf(retstr+(*slen),"%s,",w_arr[i]);
		++i;
	}
	*slen+=sprintf(retstr+(*slen),"%s",w_arr[i]);
	//slen+=sprintf(retstr+slen,"]");
	retstr[++(*slen)]='\0';
	//printf("=(%s,%d)=",retstr,*slen);
	return 0;
}

/**
 *read the index file,find all the words
 */
static void *get_words(char *filename, DICT_INFO *dict_info, WORD_IDX *word_idx)
{
	FILE *fd= fopen(filename,"rb");
	if(fd == NULL || dict_info == NULL)
		return NULL;
	printf("\ndict_info.fsize:%d:\n",dict_info->idxfilesize);
	static unsigned char buffer[1024*1024];//read the index file
	//static unsigned char buffer[dict_info->idxfilesize];//read the index file
		//return NULL;
	fread(buffer,dict_info->idxfilesize,1,fd);
	unsigned char *head,*tail;
	head=tail=buffer;
	int it=0;//cur pos;
	int total=1;//the len of word arr;
	for(; it < dict_info->idxfilesize; it++)
	{
		if(*head == '\0')//reach the end of the word
		{
			strncpy((word_idx+total)->word,tail,head-tail+1);//save the word to arr;
			(word_idx+total)->offset=to_int(head+1);//the offset of the word mean; 
			(word_idx+total)->length=to_int(head+5);//the length of the word mean;
			total++;
			head+=9;
			tail=head;
			if(total==dict_info->wordcount)break;//reach the end of file 
		}else{
			head++;
		}
	}
	return 0;
}

inline static int to_int(unsigned char *from_int)
{
	return *(from_int+3)+(*(from_int+2)<<8)+(*(from_int+1)<<16)+(*from_int<<24);
}

WORD_IDX *get_idx(char *word,WORD_IDX *word_idx, DICT_INFO *dict_info)
{
	if(word == NULL || word_idx == NULL || dict_info == NULL)return NULL;
	int head=0,tail=dict_info->wordcount,cur=tail/2;
	while(TRUE)
	{
		int cmp=strcasecmp(word,word_idx[cur].word);
		if(0 == cmp)
		{
			return &word_idx[cur];
		}else if(0 > cmp){
			tail = cur-1;
		}else{
			head = cur+1;
		}
		cur=(tail+head)/2;
		if(tail<head){
			printf("not exist---");
			return 0;
		}
	}
}


int arrindex(char *word,WORD_IDX *word_idx, DICT_INFO *dict_info)
{
	if(word == NULL || word_idx == NULL || dict_info == NULL)
	{
		return -2;
	}
	int head=0,tail=dict_info->wordcount,cur=tail/2;
	while(TRUE)
	{
		//printf("%d ",cur);
		int cmp=strcasecmp(word,word_idx[cur].word);
		if(0 == cmp)
		{
			return cur;
		}else if(0 > cmp){
			tail = cur-1;
		}else{
			head = cur+1;
		}
		cur=(tail+head)/2;
		if(tail<head){
			//printf("not exist---");
			return -1;
		}
	}
}

char arr[1024*16]="null";//word mean string 
char * getmeans(const char* wordx){
	char * filename="oxford-gb.idx";
	char * dictname="oxford-gb.dict";
	DICT_INFO dict_info;
	dict_info.wordcount=39429;
	dict_info.idxfilesize=721264;
	WORD_IDX *idx=(WORD_IDX*)malloc(sizeof(WORD_IDX)*dict_info.wordcount);
	printf("%d,%s\n",
			(int)get_words(filename,&dict_info,idx),
			wordx);
	WORD_IDX *word=get_idx((char*)wordx,idx,&dict_info);
	if(word == 0)return arr;
	printf("word:%s,offset:%d,wordLength:%d\n",word->word,word->offset,word->length);
	FILE *dict=fopen(dictname,"r");
	if(dict == NULL)
	{
		printf("dict error\n");
		return arr;
	}
	if(0 != fseek(dict,word->offset,SEEK_SET)){
		printf("seek error\n");
		return arr;
	}
	char explain[word->length+1];
	memset(explain,'\0',word->length+1);
	fread(explain,word->length,1,dict);
	free(idx);
	sprintf(arr,"%s",explain);
	return arr;
}

int findwords(const char * words,char *retstr,int*strlen)
{
	*strlen = sprintf(retstr,"%s",words);
	return 0;
}
